package com.wn.controller;


import com.wn.common.RedisConst;
import com.wn.common.enumeration.BusinessCode;
import com.wn.common.enumeration.MyAssert;
import com.wn.common.util.JwtUtil;
import com.wn.common.util.SmsUtil;
import com.wn.model.vo.LoginRequest;
import com.wn.model.vo.RegisterRequest;
import com.wn.model.vo.UserVo;
import com.wn.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.time.Duration;
import java.util.*;

@RestController
@RequestMapping("/user")
@Slf4j
@Api(tags = "用户登录")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SmsUtil smsUtil;


    /**
     * 用户注册功能
     */
    @PostMapping("/register")
    @ApiOperation("用户注册")
    public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest, HttpServletRequest request) {
        UserVo userVo = userService.register(registerRequest, request);
        return ResponseEntity.ok(userVo);
    }


    @GetMapping("/sendEmail")
    @ApiOperation("发送邮件")
    public ResponseEntity<String> sendEmail(String address) {
        userService.sendEmail(address);
        return ResponseEntity.ok("验证码已经发送到" + address + "邮箱，请去查收！");
    }


    /**
     * 发短信登录或注册
     */
    @PostMapping("/smsLogin")
    @ApiOperation("发短信登录或注册")
    public ResponseEntity<?> smsLogin(@RequestBody LoginRequest params, HttpServletRequest request) {
        UserVo userVo = userService.smsLogin(params, request);
        return ResponseEntity.ok(userVo);
    }


    /**
     * 用户名和密码，验证码登录
     */
    @PostMapping("/login")
    @ApiOperation("用户登录")
    public ResponseEntity<?> login(@RequestBody LoginRequest param, HttpServletRequest request) {
        //1.调用业务层进行登录
        UserVo userVo = userService.login(param, request);
        return ResponseEntity.ok(userVo);
    }


    /**
     * 判断用户是否登录
     * 数据从请求头中获取Token数据
     */
    @GetMapping("/isLogged")
    @ApiOperation("判断用户是否登录")
    public ResponseEntity<?> isLogged(@RequestHeader(required = false, name = "Authorization") String authorization) {
        log.info("用户请求头中携带的Token是：{}", authorization);
        //如果为空表示没有登录
        MyAssert.error(StringUtils.isEmpty(authorization), BusinessCode.USER_NOT_LOGGED);
        //判断Token是否有效
        boolean isValid = jwtUtil.validateToken(authorization);
        MyAssert.error(!isValid, BusinessCode.INVALID_TOKEN);
        //获取用户的ID
        Long userId = Long.valueOf(jwtUtil.getValue(authorization, "userId"));
        //调用业务层查询用户是否存在
        UserVo user = userService.findById(userId);
        MyAssert.error(user == null, BusinessCode.USER_NOT_EXIST);
        return ResponseEntity.ok(user);
    }

    /**
     * 退出
     */
    @DeleteMapping("/logout")
    @ApiOperation("退出")
    public ResponseEntity<String> logout(@RequestHeader("Authorization") String token, HttpServletResponse response) {
        //通过token得到用户id
        String userId = jwtUtil.getValue(token, "userId");
        //删除redis中的token
        redisTemplate.delete(RedisConst.USER_TOKEN_PREFIX + ":" + userId);
        return ResponseEntity.ok("退出成功");
    }



    /**
     * 手机号发短信
     */
    @GetMapping("/sendSms/{telephone}")
    @ApiOperation("手机号发短信")
    public ResponseEntity<String> sendSms(@PathVariable String telephone) {
        //随机生成验证码，随机生成4个数字
        String code = RandomStringUtils.randomNumeric(4);
        log.info("短信验证码：{}", code);
        //给手机号发送短信，只需要测试一次，如果成功就没有必要每次发送
//        String result = smsUtil.sendSms(telephone, code);
        String result = "成功";
        MyAssert.error(!result.equals("成功"), BusinessCode.SMS_SEND_ERROR);
        //验证码放在Redis中，10分钟过期
        redisTemplate.opsForValue().set(RedisConst.SHORT_MESSAGE_SERVICE + ":" + telephone, code, Duration.ofMinutes(10));
        String response = "给手机号：" + maskPhoneNumber(telephone) + "成功发送验证码";
        return ResponseEntity.ok(response);
    }
    /**
     * 对电话号码进行脱敏处理
     */
    private String maskPhoneNumber(String telephone) {
        // 将第4、5、6、7位替换为 *
        return telephone.substring(0, 3) + "****" + telephone.substring(7);
    }



    /**
     * 图片验证码
     */
    @GetMapping("/code")
    @ApiOperation("生成图片验证码")
    public ResponseEntity generateCaptcha() throws IOException {
        Map<String, String> data = userService.getCode();
        return ResponseEntity.ok(data);
    }



}